package org.ricks.game.hotfix;

import org.ricks.net.action.ActionReceiver;

import java.lang.classfile.*;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.AccessFlag;

import java.lang.reflect.Constructor;
import java.util.Objects;

public class BytecodeRebuilder {

    public static void rebuild(byte[] originalBytes) {
        Objects.requireNonNull(originalBytes, "原始字节码不能为空");
        ClassFile cf = ClassFile.of();
        ClassModel model = cf.parse(originalBytes);


        // 获取类的符号引用（全限定名）
        ClassDesc classDesc = model.thisClass().asSymbol();

        byte[] bytecode =  cf.build(classDesc, builder -> {
            // 1. 复制原始类的元数据（版本号、访问标志、父类、接口）
            builder.withVersion(model.majorVersion(), model.minorVersion())
                    .withFlags(model.flags().flagsMask())
                    .withSuperclass(model.superclass().orElse(null))
                    .withInterfaces(model.interfaces().toArray(ClassEntry[]::new));

            // 2. 复制非@Deprecated的方法
            model.methods().forEach(method -> {
                builder.withMethod(
                        method.methodName().stringValue(),
                        MethodTypeDesc.of(method.methodTypeSymbol().returnType(),
                                method.methodTypeSymbol().parameterArray()),
                        method.flags().flagsMask(),
                        methodBuilder -> copyMethodElements(method, methodBuilder)
                );
            });

            // 3. 添加新方法
            builder.withMethod("dynamicMethod",
                    MethodTypeDesc.ofDescriptor("()V"),
                    AccessFlag.PUBLIC.mask(),
                    methodBuilder -> methodBuilder.withCode(CodeBuilder::return_)
            );
        });
//
//        MethodHandles.Lookup lookup = MethodHandles.lookup();
//        Class<?> clazz = lookup.defineClass(bytecode);
//
//        // 创建实例
//        Constructor<?> constructor = clazz.getConstructor(beanClass);
//        return (ActionReceiver) constructor.newInstance(definition.getBean());
    }

    // 复制方法元素（属性、字节码等）
    private static void copyMethodElements(MethodModel source, MethodBuilder target) {
        source.forEach(element -> {
            if (element instanceof CodeModel codeModel) {
                target.withCode(codeBuilder -> {
                    codeModel.forEach(codeBuilder::with);
                });
            } else {
                target.with(element);
            }
        });
    }

    public static String parseFullClassName(byte[] classBytes) {
        ClassFile cf = ClassFile.of();
        ClassModel model = cf.parse(classBytes);
        String internalName = model.thisClass().name().stringValue();
        return internalName.replace('/', '.');
    }
}
